module  siopmp_check(
    input                          siopmpck_clk_i,
    input                          siopmpck_rst_n_i,
    // from siopmp_reg
    input [31:0]                   siopmpck_rule_i,
    // from siopmp_control
    input                          siopmpck_check_en_i,
    input [3:0]                    siopmpck_state_n_i,

    //from master
    input [31 : 0]                 siopmpck_haddr_i,
    input [2 : 0]                  siopmpck_hburst_i,
    input [3 : 0]                  siopmpck_hprot_i,       //hprot[0]为0，代表是来自tee的访问信号，为1，代表是来自ree的访问信号
    input                          siopmpck_hsel_i,
    input [2 : 0]                  siopmpck_hsize_i,
    input [1 : 0]                  siopmpck_htrans_i,
    input [31 : 0]                 siopmpck_hwdata_i,
    input                          siopmpck_hwrite_i,
    //from slave
    input [31 : 0]                 siopmpck_hrdata_i,
    input                          siopmpck_hready_i,
    input [1 : 0]                  siopmpck_hresp_i,
    input                          siopmpck_intr_i,

   //to slave
    
    output  [31 : 0]                siopmpck_haddr_o,
    output  [2 : 0]                 siopmpck_hburst_o,
    output  [3 : 0]                 siopmpck_hprot_o, 
    output                          siopmpck_hsel_o,
    output  [2 : 0]                 siopmpck_hsize_o,
    output  [1 : 0]                 siopmpck_htrans_o,
    output  [31 : 0]                siopmpck_hwdata_o,
    output                          siopmpck_hwrite_o,
    //to master
    output  [31 : 0]                siopmpck_hrdata_o,
    output                          siopmpck_hready_o,
    output  [1 : 0]                 siopmpck_hresp_o,
    output                          siopmpck_intr_o,
    //to siopmp_reg
    output                          siopmpck_error_o,
    output  [15:0]                  siopmpck_iohit_o,
    //to siopmp_control
    output                          siopmpck_hwren_o,
    output                          siopmpck_hrden_o,
    output                          siopmpck_hrdy_o
);




wire [31:0]    check_rule; // 修改的check规则
reg [4:0]     state;
reg [4:0]     state_next;
wire          write_en;
wire          read_en;
wire [1:0]    pri_wr;
wire          bus_ieqo;
wire [15:0]   io_hit;
reg           bus_read_check_b;
wire          bus_read_access;

//old assign bus_ieqo  = ((~siopmpck_hwrite_i & pri_wr[0]) | (siopmpck_hwrite_i & pri_wr[1]) | (siopmpck_hprot_i[0]==1'b0)) & (siopmpck_check_en_i==1'b1);

assign write_en  = (siopmpck_htrans_i[1] == 1) & (siopmpck_hwrite_i == 1) & (siopmpck_hsel_i == 1);
assign read_en   = (siopmpck_htrans_i[1] == 1) & (siopmpck_hwrite_i == 0) & (siopmpck_hsel_i == 1);
//new
assign bus_ieqo  = ((read_en & pri_wr[0]) | (write_en & pri_wr[1]) | (siopmpck_hprot_i[0]==1'b0)) & (siopmpck_check_en_i==1'b1);

assign w_r_ready = siopmpck_hready_i;

//更新检查规则
assign check_rule = siopmpck_rule_i;  //直接输出，不需要寄存，因为reg已经寄存了
// always @(posedge siopmpck_clk_i or negedge siopmpck_rst_n_i) begin
//     if(!siopmpck_rst_n_i)
//         check_rule <= 32'hFFFF_FFFC;
//     else if(siopmpck_check_en_i == 1'b0)
//         check_rule <= siopmpck_rule_i;
//     else
//         check_rule <= check_rule;
// end
//limit read after read_en 
always @(posedge siopmpck_clk_i or negedge siopmpck_rst_n_i) begin
    if(!siopmpck_rst_n_i)
        bus_read_check_b <= 1'h0;
    else if(bus_ieqo == 1'b0 && read_en == 1'b1)
        bus_read_check_b <= 1'h1;
    else if(siopmpck_state_n_i[3] == 1'b1)
        bus_read_check_b <= 1'h0;
    else
        bus_read_check_b <= bus_read_check_b;
end



assign bus_read_access = ~(bus_read_check_b & siopmpck_state_n_i[3]);

//always @(posedge siopmpck_clk_i ) begin
//    siopmpck_haddr_o  <= siopmpck_haddr_i  ;
//    siopmpck_hwrite_o <= siopmpck_hwrite_i ;
//    siopmpck_hprot_o  <= siopmpck_hprot_i  ;
//    siopmpck_hsize_o  <= siopmpck_hsize_i  ;
//    siopmpck_htrans_o <= siopmpck_htrans_i ;
//    siopmpck_hwdata_o <= siopmpck_hwdata_i ;
//    siopmpck_hburst_o <= siopmpck_hburst_i ;
//    siopmpck_hsel_o   <= (bus_ieqo == 1'b1) ? siopmpck_hsel_i : 1'b0;
//    siopmpck_hrdata_o <= siopmpck_hrdata_i;
//    siopmpck_hresp_o  <= siopmpck_hresp_i;
//    siopmpck_intr_o   <= (bus_ieqo == 1'b1) ? siopmpck_intr_i : 1'b0;
//    siopmpck_hready_o <=  siopmpck_hready_i ;
//    siopmpck_error_o  <= (bus_ieqo == 1'b1) ? 1'b0 : 1'b1;
//    siopmpck_iohit_o  <= (bus_ieqo == 1'b1) ? 16'd0 : io_hit;
//    siopmpck_hwren_o  <= write_en;
//    siopmpck_hrden_o  <= read_en;
//    siopmpck_hrdy_o   <= siopmpck_hready_i;  
//end

assign   siopmpck_haddr_o  = siopmpck_haddr_i  ;
assign   siopmpck_hwrite_o = siopmpck_hwrite_i ;
assign   siopmpck_hprot_o  = siopmpck_hprot_i  ;
assign   siopmpck_hsize_o  = siopmpck_hsize_i  ;
assign   siopmpck_htrans_o = siopmpck_htrans_i ;
assign   siopmpck_hwdata_o = siopmpck_hwdata_i ;
assign   siopmpck_hburst_o = siopmpck_hburst_i ;
assign   siopmpck_hsel_o   = (bus_ieqo == 1'b1) ? siopmpck_hsel_i : 1'b0;
assign   siopmpck_hrdata_o = (bus_read_access==1'b1) ? siopmpck_hrdata_i : 32'd0;
assign   siopmpck_hresp_o  = siopmpck_hresp_i;
assign   siopmpck_intr_o   = siopmpck_intr_i ;
assign   siopmpck_hready_o =  siopmpck_hready_i ;
assign   siopmpck_error_o  = (bus_ieqo == 1'b1) ? 1'b0 : 1'b1;
assign   siopmpck_iohit_o  = (bus_ieqo == 1'b1) ? 16'd0 : io_hit;
assign   siopmpck_hwren_o  = write_en;
assign   siopmpck_hrden_o  = read_en;
assign   siopmpck_hrdy_o   = siopmpck_hready_i;  

siopmp_addr_match u_siopmp_addr_match 
(
    .saddrmt_haddr_i (siopmpck_haddr_i),
    .saddrmt_prireg_i(check_rule),
    .saddrmt_pri_o   (pri_wr),
    .saddrmt_hit_o   (io_hit)
);

endmodule
